<?php

namespace App\Http\Controllers\Api;

use App\Exceptions\ResponseException;
use App\Handler\Wechat\TextMsgHandler; //事件处理
use App\Models\WechatUser;
use EasyWeChat\Factory;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class WechatController extends Controller
{
	use TextMsgHandler;
	//服务验证
	public function server()
    {
		$app = app('wechat.official_account');

		$app->server->push(function ($message){
			// $message['FromUserName'] // 用户的 openid
			// $message['MsgType'] // 消息类型：event, text....
			switch ($message['MsgType']) {
				case 'event':
					return '收到事件消息';
					break;
				case 'text':
					//文字消息，传给专门的hanlder去处理
					return $this->textMsgHandler($message);
					break;
				case 'image':
					return '收到图片消息';
					break;
				case 'voice':
					return '收到语音消息';
					break;
				case 'video':
					return '收到视频消息';
					break;
				case 'location':
					return '收到坐标消息';
					break;
				case 'link':
					return '收到链接消息';
					break;
				case 'file':
					return '收到文件消息';
				// ... 其它消息
				default:
					return '收到其它消息';
					break;
			}

		});

		//返回给微信前台
		$response = $app->server->serve();

		return $response;
    }

    /**
     * 获取jssdk的验证参数
     * User: Clannad ~ ☆
     * DataTime：2020/7/29 0029 21:02
     * @throws ResponseException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function getJsSdkParams()
    {

        $app = Factory::officialAccount(config('wechat.official_account.default'));

        $APIs = [
            'updateAppMessageShareData',
            'updateTimelineShareData'
        ];

        $url = \request()->input('url');
        $app->jssdk->setUrl($url);
        $share_api = $app->jssdk->buildConfig($APIs, $debug = true, $beta = false, $json = true);

        throw new ResponseException(200,'ok',$share_api);
    }


    // 获取签名
    public function getSignPackage() {
        // 获取token
        $token = WechatUser::query()->where([
            'user_id'=>auth('api')->id()
        ])->value('access_token');
        // 获取ticket
        $ticketList = $this->getJsApiTicket($token);
        $ticket = $ticketList['ticket'];
        // 该URL为使用JSSDK接口的URL
        $url = $_GET['url'];
        if (!$url) {
            $url = 'http://vuetest.17hxg.com';
        }
        // 时间戳
        $timestamp = time();
        // 随机字符串
        $nonceStr = $this->createNoncestr();
        // 这里参数的顺序要按照 key 值 ASCII 码升序排序 j -> n -> t -> u
        $string = "jsapi_ticket=$ticket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";
        $signature = sha1($string);
        $signPackage = array (
            "appId" => 'wx876213c6af12013a',
            "nonceStr" => $nonceStr,
            "timestamp" => $timestamp,
            "url" => $url,
            "signature" => $signature,
            "rawString" => $string,
            "ticket" => $ticket,
            "token" => $token
        );
        // 提供数据给前端
        $this->ajaxReturn(array('status' => true, 'data' => $signPackage));
    }

// 创建随机字符串
    private function createNoncestr($length = 16) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for($i = 0; $i < $length; $i ++) {
            $str .= substr ( $chars, mt_rand ( 0, strlen ( $chars ) - 1 ), 1 );
        }
        return $str;
    }

    public function getJsApiTicket($accessToken) {
        // jsapi_ticket 应该全局存储与更新
        // 获取数据库中的jsapi_ticket
        $ticket = M('jsticket')->limit(1)->find();
        $paseTime = strtotime($ticket['time']);
        // 如果ticket失效
        if($time + $token['expiresIn'] < time() || $ticket['ticket'] == NULL){
            $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$accessToken&&type=jsapi";
            // 微信返回的信息
            $returnData = json_decode($this->httpGet($url));
            // 组装数据
            $resData['ticket'] = $returnData->ticket;
            $resData['expiresIn'] = $returnData ->expires_in;
            $resData['time'] = date("Y-m-d H:i",time());
            $resData['errcode'] = $returnData->errcode;
            // 把数据存进数据库
            M('jsticket')->where(array('id' => $ticket['id']))->save($resData);
            $res = $resData;
        }else{
            $res = $ticket;
        }
        return $res;
    }

    private function httpGet($url) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true );
        curl_setopt($curl, CURLOPT_TIMEOUT, 500 );
        curl_setopt($curl, CURLOPT_URL, $url );
        $res = curl_exec($curl);
        curl_close($curl);
        return $res;
    }

    public function getAccessToken() {
        // access_token 应该全局存储与更新
        // 获取数据库中的access_token
        $token = M('accesstoken')->limit(1)->find();
        // 如果数据库存在token
        if ($token) {
            // 格式化数据库的timestamp
            $time = strtotime($token['time']);
        }
        // accessToken过期或不存在时
        if($time + $token['expiresIn'] < time() || $token['accessToken'] == NULL){
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".C('WxPayConf_pub.APPID')."&secret=".C('WxPayConf_pub.APPSECRET');
            // 微信返回的信息
            $returnData = json_decode($this->httpGet($url));
            // 组装数据
            $resData['accessToken'] = $returnData->access_token;
            $resData['expiresIn'] = $returnData->expires_in;
            $resData['time'] = date("Y-m-d H:i",time());
            // 把数据存进数据库
            M('accesstoken')->where(array('id' => $token['id']))->save($resData);
            $res = $resData;
        }else{
            $res = $token;
        }
        return $res;
    }

}
